package com.gitee.feizns.itrip.personal.utils.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.gitee.feizns.itrip.personal.utils.service.AliPayService;
import lombok.Data;
import lombok.experimental.Accessors;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author feizns
 * @since 2019/1/13 0013
 */
public class AliPayServiceImpl implements AliPayService {

    private AliPayConfig aliPayConfig;

    private AlipayClient alipayClient;

    public AliPayServiceImpl(AliPayConfig aliPayConfig) {
        this.aliPayConfig = aliPayConfig;
        this.alipayClient =
                new DefaultAlipayClient(
                        aliPayConfig.getGatewayUrl(),
                        aliPayConfig.getAppId(),
                        aliPayConfig.getMerchantPrivateKey(),
                        aliPayConfig.getFormat(),
                        aliPayConfig.getCharset(),
                        aliPayConfig.getAliPayPublicKey(),
                        aliPayConfig.getSignType());
    }

    @Override
    public String send(String outTradeNo, String totalAmount, String subject, String body) {
        AlipayTradePagePayRequest aliPayRequest = new AlipayTradePagePayRequest();

        aliPayRequest.setReturnUrl(aliPayConfig.getReturnUrl());
        aliPayRequest.setNotifyUrl(aliPayConfig.getNotifyUrl());
        aliPayRequest.setBizModel(createTradeModel(outTradeNo, totalAmount, subject, null));

        try {
            return alipayClient.pageExecute(aliPayRequest).getBody();
        } catch (AlipayApiException e) {
            throw new RuntimeException("发送失败.");
        }
    }

    @Override
    public boolean rsaCheckV1(HttpServletRequest req) {
        try {
            return AlipaySignature.rsaCheckV1(
                    parseParameter(
                            req.getParameterMap()),
                            aliPayConfig.aliPayPublicKey,
                            aliPayConfig.charset,
                            aliPayConfig.signType);
        } catch (AlipayApiException e) {
            return false;
        }
    }

    private AlipayTradeWapPayModel createTradeModel(String outTradeNo, String totalAmount, String subject, String body) {
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(outTradeNo);
        model.setTotalAmount(totalAmount);
        model.setSubject(subject);
        if ( body != null )
            model.setBody(body);
        model.setProductCode(PRODUCT_CODE);
        return model;
    }

    private Map<String, String> parseParameter(Map<String, String[]> requestParams) {
        Map<String, String> params = new HashMap<>();
        for (Iterator<String> iterator = requestParams.keySet().iterator(); iterator.hasNext();) {
            String name = (String) iterator.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        return params;
    }

    /**
     * 支付宝信息配置类
     */
    @Data
    public static class AliPayConfig {

        /**
         * 应用ID,您的appID，收款账号既是您的appID对应支付宝账号
         */
        private String appId;

        /**
         * 商户私钥，您的 PKCS8格式RSA2私钥
         */
        private String merchantPrivateKey;

        /**
         * 支付宝公钥,查看地址：https://openhome.alipay.com/platform/keyManage.htm 对应AppID下的支付宝公钥。
         */
        private String aliPayPublicKey;

        /**
         * 服务器异步通知页面路径  需http://格式的完整路径，不能加?id=123这类自定义参数，必须外网可以正常访问
         */
        private String notifyUrl;

        /**
         * 页面跳转同步通知页面路径 需http://格式的完整路径，不能加?id=123这类自定义参数，必须外网可以正常访问
         */
        private String returnUrl;

        /**
         * 发送数据格式
         */
        private String format = DEFAULT_FORMAT;

        /**
         * 签名方式
         */
        private String signType = DEFAULT_SIGN_TYPE;

        /**
         * 字符编码格式
         */
        private String charset = DEFAULT_CHARSET;

        /**
         * 支付宝网关
         */
        private String gatewayUrl = DEV_GATEWAY_URL;

    }

    @Data
    @Accessors(chain = true)
    private class AliPayBizContent {

        private String out_trade_no;

        private String total_amount;

        private String subject;

        private String body;

        private String product_code;

    }

}
